package com.ssy.lingxi.component.redis.serviceImpl;

import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.component.redis.config.RedisModeDetector;
import com.ssy.lingxi.component.redis.config.SerializeUtils;
import com.ssy.lingxi.component.redis.service.IRedisUtils;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * redisUtils实现类(用于存储所有类型数据,存储之前会进行序列化)
 * @author jw.chen
 * @date 2020-08-01
 */
@Repository("redisUtils")
public class RedisUtilsImpl implements IRedisUtils {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private RedisModeDetector detector;

    static Long size = 0L;

    /**
     * 保存数据
     * @param key   key值
     * @param obj   value值
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public Boolean set(String key, Object obj, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return false;
            }

            byte[] redis_value = SerializeUtils.serialize(obj);
            return con.set(redis_key, redis_value);
        });
    }

    /**
     * 保存数据并设置超时时间
     * @param key    key值
     * @param obj    value值
     * @param expire 超时时间，单位 秒
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public Boolean set(String key, Object obj, Long expire, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return false;
            }

            byte[] redis_value = SerializeUtils.serialize(obj);
            con.set(redis_key, redis_value);
            if (expire != null && expire > 0) {
                con.expire(redis_key, expire);
            }
            return true;
        });
    }

    /**
     * 批量保存数据
     * @param keyValueList   key和value值
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public List<Boolean> setBatch(Map<String, Object> keyValueList, Integer db_index) {
        List<Object> list = redisTemplate.executePipelined((RedisCallback<Object>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            for (Map.Entry<String, Object> entry : keyValueList.entrySet()) {
                String key = entry.getKey();
                Object obj = entry.getValue();
                byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
                if(redis_key == null) {
                    return false;
                }

                byte[] redis_value = SerializeUtils.serialize(obj);
                con.set(redis_key, redis_value);
            }
            return null;
        });
        return list.stream().map(o -> Boolean.valueOf(String.valueOf(o))).collect(Collectors.toList());
    }


    /**
     * 获取key对应的实体对象
     * @param key key值
     * @param db_index redis数据库下标
     * @param clazz 实体类的Class
     * @return 查询结果
     */
    @Override
    public <T> T get(String key, Integer db_index, Class<T> clazz) {
        Object obj = get(key, db_index);
        return obj == null ? null : JSONUtil.parse(obj).toBean(clazz);
    }

    /**
     * 获取key对应的值
     * @param key   key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Object get(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Object>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_value = redisTemplate.getStringSerializer().serialize(key);
            return redis_value == null ? null : SerializeUtils.deserialize(con.get(redis_value));
        });
    }

    /**
     * 批量获取key对应的值
     * @param keyList   key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public List<Object> getBatch(List<String> keyList, Integer db_index) {
        return redisTemplate.executePipelined((RedisCallback<Object>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            keyList.forEach(key -> {
                byte[] redis_value = redisTemplate.getStringSerializer().serialize(key);
                SerializeUtils.deserialize(redis_value == null ? null : con.get(redis_value));
            });
            return null;
        });
    }

    /**
     * 删除指定的key
     * @param key  key值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long del(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return con.del(redis_key);
        });
    }

    /**
     * 删除指定的key
     * @param keys  keys值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long del(List<String> keys, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[][] redis_keys = (byte[][]) keys.stream().map(key -> redisTemplate.getStringSerializer().serialize(key)).toArray();
            return con.del(redis_keys);
        });
    }

    /**
     * 以秒为单位，返回给定key的剩余生存时间
     * @param key   key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Long ttl(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.ttl(redis_key);
        });
    }

    /**
     * 以毫秒为单位，返回给定key的剩余生存时间
     * @param key   key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Long pTtl(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.pTtl(redis_key);
        });
    }

    /**
     * 判断key是否存在
     * @param key   key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Boolean exists(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return false;
            }

            return con.exists(redis_key);
        });
    }

    /**
     * 判断存在多少个key
     * @param keys   keys值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Long exists(List<String> keys, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[][] redis_keys = (byte[][]) keys.stream().map(key -> redisTemplate.getStringSerializer().serialize(key)).toArray();
            return con.exists(redis_keys);
        });
    }

    /**
     * 查找所有符合给定模式 pattern 的 key
     * @param key
     *      KEYS * 匹配数据库中所有 key 。
     *      KEYS h?llo 匹配 hello ， hallo 和 hxllo 等。
     *      KEYS h*llo 匹配 hllo 和 heeeeello 等。
     *      KEYS h[ae]llo 匹配 hello 和 hallo ，但不匹配 hillo
     * @return 查询结果
     */
    @Override
    public List<Object> searchKey(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<List<Object>>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return new ArrayList<>();
            }

            Set<byte[]> redis_keys = con.keys(redis_key);
            if(redis_keys != null && redis_keys.size() > 0){
                return redis_keys.stream().map(SerializeUtils::deserialize).collect(Collectors.toList());
            }else{
                return null;
            }
        });
    }

    /**
     * 查找所有符合给定模式pattern的key的个数
     * @param key
     *      KEYS * 匹配数据库中所有 key 。
     *      KEYS h?llo 匹配 hello ， hallo 和 hxllo 等。
     *      KEYS h*llo 匹配 hllo 和 heeeeello 等。
     *      KEYS h[ae]llo 匹配 hello 和 hallo ，但不匹配 hillo
     * @return 查询结果
     */
    @Override
    public int size(String key, Integer db_index) {
        List<Object> result = this.searchKey(key, db_index);
        if(result != null && !result.isEmpty()){
            return result.size();
        }
        return 0;
    }

    /**
     * 递增1
     * @param key key值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long increment(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.incr(redis_key);
        });
    }

    /**
     * 递增
     * @param key key值
     * @param data 累加值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long increment(String key, long data, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.incrBy(redis_key, data);
        });
    }
    /**
     * 递增
     * @param key key值
     * @param data 累加值
     * @param db_index   redis数据库下标
     */
    @Override
    public Double increment(String key, double data, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Double>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.incrBy(redis_key, data);
        });
    }

    /**
     * 递减1
     * @param key key值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long decrement(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.decr(redis_key);
        });
    }

    /**
     * 递减
     * @param key key值
     * @param data 累加值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long decrement(String key, long data, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            return redis_key == null ? null : con.decrBy(redis_key, data);
        });
    }

    /**
     * 保存数据
     * @param key   key值
     * @param field   field值
     * @param obj   value值
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public Boolean hSet(String key, String field, Object obj, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            byte[] redis_value = SerializeUtils.serialize(obj);
            return (redis_key == null || redis_field == null) ? null : con.hSet(redis_key, redis_field, redis_value);
        });
    }

    /**
     * 保存数据并设置超时时间
     * @param key    key值
     * @param field   field值
     * @param obj    value值
     * @param expire 超时时间，单位 秒
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public Boolean hSet(String key, String field, Object obj, Long expire, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            byte[] redis_value = SerializeUtils.serialize(obj);
            if(redis_key == null || redis_field == null) {
                return false;
            }

            con.hSet(redis_key, redis_field, redis_value);
            if (expire != null && expire > 0) {
                con.expire(redis_key, expire);
            }
            return true;
        });
    }

    /**
     * 获取key对应的值
     * @param key   key值
     * @param field   field值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Object hGet(String key, String field, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Object>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_value = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            return (redis_value == null || redis_field == null) ? null : SerializeUtils.deserialize(con.hGet(redis_value, redis_field));
        });
    }

    /**
     * 保存数据
     * @param key   key值
     * @param value   value值
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public Boolean hMSet(String key, Map<String, String> value, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            //将value的map转成byte[]
            Map<byte[], byte[]> map = new HashMap<>();
            for (Map.Entry<String, String> entry : value.entrySet()) {
                map.put(redisTemplate.getStringSerializer().serialize(entry.getKey()), redisTemplate.getStringSerializer().serialize(entry.getValue()));
            }

            if(redis_key == null) {
                return false;
            }

            con.hMSet(redis_key, map);
            return true;
        });
    }

    /**
     * 保存数据并设置超时时间
     * @param key    key值
     * @param value    value值
     * @param expire 超时时间，单位 秒
     * @param db_index   redis数据库下标
     * @return 保存结果
     */
    @Override
    public Boolean hMSet(String key, Map<String, String> value, Long expire, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            //将value的map转成byte[]
            Map<byte[], byte[]> map = new HashMap<>();
            for (Map.Entry<String, String> entry : value.entrySet()) {
                map.put(redisTemplate.getStringSerializer().serialize(entry.getKey()), redisTemplate.getStringSerializer().serialize(entry.getValue()));
            }

            if(redis_key == null) {
                return false;
            }

            con.hMSet(redis_key, map);
            if (expire != null && expire > 0) {
                con.expire(redis_key, expire);
            }
            return true;
        });
    }

    /**
     * 获取key对应的值
     * @param key   key值
     * @param fields   fields值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public List<Object> hMGet(String key, String[] fields, Integer db_index) {
        return redisTemplate.execute((RedisCallback<List<Object>>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[][] redis_fields = new byte[fields.length][];
            for(int i = 0; i < fields.length; i++) {
                redis_fields[i] = redisTemplate.getStringSerializer().serialize(fields[i]);
            }

            if(redis_key == null) {
                return new ArrayList<>();
            }

            List<byte[]> valueList = con.hMGet(redis_key, redis_fields);
            return CollectionUtils.isEmpty(valueList) ? new ArrayList<>() : valueList.stream().map(SerializeUtils::deserialize).collect(Collectors.toList());
        });
    }

    /**
     * 获取key对应的值
     * @param key   key值
     * @param field   field值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Object hMGet(String key, String field, Integer db_index) {
        List<Object> valueList = this.hMGet(key, new String[]{field}, db_index);
        if(valueList != null && !valueList.isEmpty()){
            return valueList.get(0);
        }else{
            return null;
        }
    }

    /**
     * 获取key对应的值
     * @param key   key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Map<String, Object> hGetAll(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Map<String, Object>>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return new HashMap<>();
            }

            Map<byte[], byte[]> redis_value = con.hGetAll(redis_key);
            if(redis_value == null) {
                return new HashMap<>();
            }

            Map<String, Object> map = new HashMap<>();
            for (Map.Entry<byte[], byte[]> entry : redis_value.entrySet()) {
                map.put(String.valueOf(SerializeUtils.deserialize(entry.getKey())), SerializeUtils.deserialize(entry.getValue()));
            }
            return map;
        });
    }

    /**
     * 删除指定的key
     * @param key  key值
     * @param field   field值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long hDel(String key, String field, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            return redis_key == null ? null : con.hDel(redis_key, redis_field);
        });
    }

    /**
     * 删除指定的key
     * @param key  key值
     * @param fields  keys值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long hDel(String key, List<String> fields, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[][] redis_fields = (byte[][]) fields.stream().map(field -> redisTemplate.getStringSerializer().serialize(field)).toArray();
            return redis_key == null ? null : con.hDel(redis_key, redis_fields);
        });
    }

    /**
     * 判断key是否存在
     * @param key   key值
     * @param field   field值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Boolean hExists(String key, String field, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Boolean>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            if(redis_key == null || redis_field == null) {
                return false;
            }

            return con.hExists(redis_key, redis_field);
        });
    }

    /**
     * 判断存在多少个key
     * @param key   key值
     * @param fields   keys值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public Long hExists(String key, List<String> fields, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return 0L;
            }

            fields.forEach(field -> {
                byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
                if(redis_field != null) {
                    Boolean exists = con.hExists(redis_key, redis_field);
                    if (exists != null && exists) {
                        size++;
                    }
                }
            });
            return size;
        });
    }

    /**
     * 查找所有符合给定模式pattern的key中的所有field
     * @param key key值
     * @param db_index   redis数据库下标
     * @return 查询结果
     */
    @Override
    public List<Object> searchHKey(String key, Integer db_index) {
        return redisTemplate.execute((RedisCallback<List<Object>>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            if(redis_key == null) {
                return null;
            }

            Set<byte[]> redis_fields = con.hKeys(redis_key);
            if(redis_fields != null && redis_fields.size() > 0){
                return redis_fields.stream().map(SerializeUtils::deserialize).collect(Collectors.toList());
            }else{
                return null;
            }
        });
    }

    /**
     * 查找所有符合给定模式pattern的key中的所有field的个数
     * @param key key值
     * @return 查询结果
     */
    @Override
    public int hSize(String key, Integer db_index) {
        List<Object> result = this.searchHKey(key, db_index);
        if(result != null && !result.isEmpty()){
            return result.size();
        }
        return 0;
    }

    /**
     * 递增1
     * @param key key值
     * @param field   field值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long hIncrement(String key, String field, Integer db_index) {
        return this.hIncrement(key, field, 1, db_index);
    }

    /**
     * 递增
     * @param key key值
     * @param field   field值
     * @param data 累加值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long hIncrement(String key, String field, long data, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            if(redis_key == null || redis_field == null) {
                return null;
            }

            return con.hIncrBy(redis_key, redis_field, data);
        });
    }

    /**
     * 递增
     * @param key key值
     * @param field   field值
     * @param data 累加值
     * @param db_index   redis数据库下标
     */
    @Override
    public Double hIncrement(String key, String field, double data, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Double>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            if(redis_key == null || redis_field == null) {
                return 0D;
            }

            return con.hIncrBy(redis_key, redis_field, data);
        });
    }

    /**
     * 递减1
     * @param key key值
     * @param field   field值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long hDecrement(String key, String field, Integer db_index) {
        return this.hDecrement(key, field, 1, db_index);
    }

    /**
     * 递减
     * @param key key值
     * @param field   field值
     * @param data 累加值
     * @param db_index   redis数据库下标
     */
    @Override
    public Long hDecrement(String key, String field, long data, Integer db_index) {
        return redisTemplate.execute((RedisCallback<Long>) con -> {
            con.select(detector.isCluster() ? 0 : db_index == null ? 0 : db_index);
            byte[] redis_key = redisTemplate.getStringSerializer().serialize(key);
            byte[] redis_field = redisTemplate.getStringSerializer().serialize(field);
            if(redis_key == null || redis_field == null) {
                return 0L;
            }

            return con.hIncrBy(redis_key, redis_field, -data);
        });
    }
}
